package org.linlinjava.litemall.admin.job;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 检测订单状态
 */
@Component
public class OrderJob {
    private final Log logger = LogFactory.getLog(OrderJob.class);

    @Autowired
    private LitemallOrderGoodsService orderGoodsService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private LitemallGoodsProductService productService;
    @Autowired
    private LitemallGrouponService grouponService;
    @Autowired
    private LitemallGrouponRulesService rulesService;

    @Autowired
    LitemallUserService userService;
    @Autowired
    private LitemallPointsRecordService pointsRecordService;


    /**
     * 自动确认订单
     * <p>
     * 定时检查订单未确认情况，如果超时 LITEMALL_ORDER_UNCONFIRM 天则自动确认订单
     * 定时时间是每天凌晨3点。
     * <p>
     * TODO
     * 注意，因为是相隔一天检查，因此导致订单真正超时时间是 [LITEMALL_ORDER_UNCONFIRM, 1 + LITEMALL_ORDER_UNCONFIRM]
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void checkOrderUnconfirm() {
        logger.info("系统开启定时任务检查订单是否已经超期自动确认收货");

        List<LitemallOrder> orderList = orderService.queryUnconfirm(SystemConfig.getOrderUnconfirm());
        for (LitemallOrder order : orderList) {

            // 设置订单已取消状态
            order.setOrderStatus(OrderUtil.STATUS_AUTO_CONFIRM);
            order.setConfirmTime(LocalDateTime.now());
            if (orderService.updateWithOptimisticLocker(order) == 0) {
                logger.info("订单 ID=" + order.getId() + " 数据已经更新，放弃自动确认收货");
            } else {
                logger.info("订单 ID=" + order.getId() + " 已经超期自动确认收货");
            }

            // =====================给代理分配奖励---梨膏糖
            //当前订单需要支付的费用
            double  price= Double.parseDouble(order.getOrderPrice().toString());
            Double integral = price;
            updateUserIntegral(order.getUserId(),integral,order);
            // ==========================给代理分配奖励---梨膏糖

        }



        logger.info("系统结束定时任务检查订单是否已经超期自动确认收货");
    }

    /**
     * 可评价订单商品超期
     * <p>
     * 定时检查订单商品评价情况，如果确认商品超时 LITEMALL_ORDER_COMMENT 天则取消可评价状态
     * 定时时间是每天凌晨4点。
     * <p>
     * TODO
     * 注意，因为是相隔一天检查，因此导致订单真正超时时间是 [LITEMALL_ORDER_COMMENT, 1 + LITEMALL_ORDER_COMMENT]
     */
    @Scheduled(cron = "0 0 4 * * ?")
    public void checkOrderComment() {
        logger.info("系统开启任务检查订单是否已经超期未评价");

        List<LitemallOrder> orderList = orderService.queryComment(SystemConfig.getOrderComment());
        for (LitemallOrder order : orderList) {
            order.setComments((short) 0);
            orderService.updateWithOptimisticLocker(order);

            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(order.getId());
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                orderGoods.setComment(-1);
                orderGoodsService.updateById(orderGoods);
            }
        }

        logger.info("系统结束任务检查订单是否已经超期未评价");
    }


    /**
     * 定时任务调用该方法
     * 该方法作为支付宝支付成功后，对用户邀请人以及用户链做积分变更的方法
     * @param userId 支付成功的用户id
     * @param integral 支付成功的金额
     */
    public void updateUserIntegral(Integer userId, Double integral,LitemallOrder order) {
        logger.info("触发积分奖励，userId="+userId+",订单金额="+integral);
        if (integral >= 0) {
            LitemallUser direct = null; // 用户的直接邀请人
            LitemallUser indirect = null; // 用户的间接邀请人
            Integer directInviteeId = null; // 用户的直接邀请人id
            Integer indirectInviteeId = null; // 用户的间接邀请人id
            String[] userlian = null; // 用户链
            Integer proProxyId = null; // 省代id
            Integer cityProxyId = null; // 市代id
            Integer coutProxyId = null; // 县代id
            LitemallUser tmpUser; // 代理的临时操作对象
            //以id找出用户
            LitemallUser user = userService.findById(userId);
            if (user != null) {
                //获取直接邀请人和间接邀请人的id
                directInviteeId = user.getDirectInvitee();
                indirectInviteeId = user.getIndirectInvitee();
                //判断是否存在直接邀请人和间接邀请人
                if (directInviteeId != 0 && (direct = userService.findById(directInviteeId)) != null) {
                    // 根据规则用户购买物品时邀请人会得到用户所花费的金额乘以百分之几的积分加成;
                    direct.setIntegral(direct.getIntegral() + integral * 0.06);
                    // 直接保存
                    userService.updateById(direct);
                    //记录积分记录
                    pointsRecordService.inviteeReward(direct.getId(),userId,  integral * 0.06,order, "1");
                }

                if (indirectInviteeId != 0 && (indirect = userService.findById(indirectInviteeId)) != null) {
                    indirect.setIntegral(indirect.getIntegral() + integral * 0.04);
                    userService.updateById(indirect);
                    //记录积分记录
                    pointsRecordService.inviteeReward(indirect.getId(),userId,  integral * 0.04,order, "2");
                }

                // 处理代理的积分增加
                if (StringUtils.hasText(user.getUserlian()) && (userlian = user.getUserlian().split(",")).length >= 1) {
                    // 遍历每个用户id
                    for (int i = userlian.length - 1; i >= 0; i--) {
                        int proxyId = Integer.parseInt(userlian[i]);
                        boolean flag = false; // 后续做判断，若出现需要保存的代理用户，就更改flag，最后做判断是否保存
                        int level;
                        Double addIntegral = 0d;
                        tmpUser = userService.findById(proxyId); // 根据id找到用户
                        if (tmpUser != null && 0 != (level = tmpUser.getServeCenter())) { // 判断是否是代理
                            if (coutProxyId == null && 3 == level && cityProxyId == null) {
                                addIntegral = integral * 0.05;
                                tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                coutProxyId = proxyId;
                                flag = true;
                            } else if (cityProxyId == null && 2 == level) {
                                if (coutProxyId == null) { // 县代是空，市代拿 3+5=8
                                    addIntegral = integral * 0.08;
                                    tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                    cityProxyId = proxyId;
                                    flag = true;
                                }else {
                                    addIntegral = integral * 0.03;
                                    tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                    cityProxyId = proxyId;
                                    flag = true;
                                }
                            } else if (proProxyId == null && 1 == level) { // 先判断是否已经记录了代理的id，没记录就对该用户做积分奖励
                                if (coutProxyId == null && cityProxyId == null){
                                    addIntegral = integral * 0.1;
                                    tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                    proProxyId = proxyId;// 记录代理用户的id
                                    flag = true; // flag做变动，后续会对该用户保存操作
                                } else if (cityProxyId == null && coutProxyId != null) {
                                    addIntegral = integral * 0.05;
                                    tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                    proProxyId = proxyId;// 记录代理用户的id
                                    flag = true; // flag做变动，后续会对该用户保存操作
                                } else if (coutProxyId != null && cityProxyId != null) {
                                    addIntegral = integral * 0.02;
                                    tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                    proProxyId = proxyId;// 记录代理用户的id
                                    flag = true; // flag做变动，后续会对该用户保存操作
                                } else if (cityProxyId != null && coutProxyId == null) {
                                    addIntegral = integral * 0.02;
                                    tmpUser.setIntegral(tmpUser.getIntegral() + addIntegral);
                                    proProxyId = proxyId;// 记录代理用户的id
                                    flag = true; // flag做变动，后续会对该用户保存操作
                                }
                            }
                            if (flag) {
                                userService.updateById(tmpUser);
                                //增加积分记录
                                pointsRecordService.proxyReward(tmpUser.getId(), userId, addIntegral,order, Integer.toString(level));

                            }
                            if (proProxyId != null) {// 如果已经找到了省代，说明后续不用再找了，直接终结循环
                                break;
                            }
                        }
                    }
                }
            }
        }

    }

}
